<?php

/**
 * Mundy
 * A Minimal Framework for PHP.
 *
 * @author      Adrian Unger <unger.adrian@gmail.com>
 * @link        http://staydecent.ca
 * @license     http://www.opensource.org/licenses/mit-license.php MIT License
 * @version     0.2.0, incomplete
 */
class Mundy
{
    public  $route, $parts,
            $m_path,
            $v_path,
            $c_path, $c_default = 'Main';

    private $file,
            $controller, $action, $args;

    /**
     * @param array $vars Sets variables
     * @param boolean $quick If true the methods are called automatically
     */
    public function __construct($vars = '', $quick = true)
    {
        if(is_array($vars))
            foreach($vars as $k => $v)
                $this->$k = (stristr($k, 'path')) ? $v . '/' : $v;

        if($quick)
            $this->determine()->set()->run();
    }

    /**
     * Determines the controller, action & args.
     */
    public function determine()
    {
        $this->route = (empty($_GET['route'])) ? $this->c_default : trim($_GET['route'], '/\\');
        $this->parts = explode('/', $this->route);

        foreach($this->parts as $part) {
            $path = $this->c_path . $part;

            if(is_dir($path)) {
                $this->c_path .= $part . '/';
                array_shift($this->parts);
                continue;
            }

            if(is_file($path . '.php')) {
                $this->controller = $part;
                array_shift($this->parts);
                break;
            }
        }

        return $this;
    }

    /**
     * @param string $controller Set controller, if not already set
     * @param string $action Set action, if not already set
     * @param string $args Set args, if not already set
     */
    public function set($controller = null, $action = null, $args = null)
    {
        if(is_array($this->parts))
                array_shift($this->parts);

        if(empty($this->controller))
            $this->controller = (is_null($controller)) ? $this->c_default : $controller;

        $this->file = $this->c_path . $this->controller . '.php';

        if(is_array($this->parts))
            $this->action = array_shift($this->parts);
        if(is_null($this->action))
            $this->action = (is_null($action)) ? strtoupper($_SERVER['REQUEST_METHOD']) : $action;

        $this->args = $this->parts;

        return $this;
    }

    /**
     * Calls the controller & action.
     */
    public function run()
    {
        if(class_exists($this->controller, false)) {
            $object = new $this->controller;
            $object->set_paths(array(
                'v_path' => $this->v_path,
                'm_path' => $this->m_path
            ));

            if(method_exists($object, $this->action))
                return call_user_func_array(array($object, $this->action), $this->args);
            else throw new Exception("The action was not callable &ldquo;$this->controller->$this->action&rdquo;");
        }
        elseif(is_file($this->file)) {
            include $this->file;
            $this->run(); # Recursion!
        }
        else throw new Exception("The controller could not be loaded &ldquo;$this->file&rdquo;");

        return $this;
    }
}

/**
 * @var array $vars For passing vars to the view
 */
abstract class Controller
{
    public  $m_path,
            $v_path;

    private $vars;

    /**
     * @param array $arr Assoc array for the model and view paths
     */
    public function set_paths($arr)
    {
        if(is_array($arr))
            foreach($arr as $k => $v)
                $this->$k = $v . '/';
    }

    /**
     * @param string $view The name of the view file
     * @param array $vars Associative array to pass vars for use in the view file
     */
    public function render($view, $vars = array())
    {
        $file = $this->v_path . '/' . $view . '.php';
        extract($vars);

        ob_start();
        include $file;
        $out = ob_get_contents();
        ob_end_clean();

        echo $out;
    }
}

# EOF: Mundy.php